home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Emulators / v2600 / Source.lha / Source / files.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  4.8 KB  |  229 lines

  1. /*****************************************************************************
  2.  
  3.    This file is part of x2600, the Atari 2600 Emulator
  4.    ===================================================
  5.    
  6.    Copyright 1996 Alex Hornby. For contributions see the file CREDITS.
  7.  
  8.    This software is distributed under the terms of the GNU General Public
  9.    License. This is free software with ABSOLUTELY NO WARRANTY.
  10.    
  11.    See the file COPYING for details.
  12.    
  13.    Tweaked by Matthew Stroup for Amiga v2600, April 24, 1997.
  14.  
  15. ******************************************************************************/
  16.  
  17. /*
  18.    Used to load cartridge images into memory.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24. #include <string.h>
  25. #include "types.h"
  26. #include "vmachine.h"
  27. #include "c26def.h"
  28. #include "options.h"
  29. #include "config.h"
  30.  
  31. /* Return the size of the file pointed to by fp */
  32. /* Avoids need for UNIX type stat, leaves file */
  33. /* pointer untouched. */
  34. long filesize (FILE * fp)
  35. {
  36.   long curpos, length;
  37.  
  38.   curpos = ftell (fp);
  39.   fseek (fp, 0L, SEEK_END);
  40.   length = ftell (fp);
  41.   fseek (fp, curpos, SEEK_SET);
  42.   return length;
  43. }
  44.  
  45. /* Load from the common 2600 format */
  46. /* Uses the tag structure from c26def.h */
  47. int loadc26 (FILE * fp, long flen)
  48. {
  49.   char databuf[65535];
  50.   struct c26_tag tag;
  51.  
  52.   while (fread (&tag, sizeof (struct c26_tag), 1, fp))
  53.     {
  54.       /* If positive then it has a data block */
  55.       if (tag.type >= 0)
  56.     {
  57.       if (fread (databuf, sizeof (UBYTE), tag.len, fp))
  58.         {
  59.           perror ("x2600 loadc26:");
  60.           fprintf (stderr, "Error reading data.\n");
  61.         }
  62.     }
  63.  
  64.       switch (tag.type)
  65.     {
  66.  
  67.     case VERSION:
  68.       if (Verbose)
  69.         printf ("File version %d\n", tag.len);
  70.       break;
  71.  
  72.     case WRITER:
  73.       if (Verbose)
  74.         printf ("Written by: %s\n", databuf);
  75.       break;
  76.  
  77.     case TVTYPE:
  78.       base_opts.tvtype = tag.len;
  79.       break;
  80.  
  81.     case CONTROLLERS:
  82.       /* Higher byte */
  83.       base_opts.lcon = (tag.len & 0xff00)>>8;
  84.       /* Low byte */
  85.       base_opts.rcon = (tag.len) & 0xff;
  86.  
  87.     case BANKING:
  88.       base_opts.bank = tag.len;
  89.       break;
  90.  
  91.     case DATA:
  92.       if (tag.len <= 16384)
  93.         memcpy (&theCart[0], databuf, tag.len);
  94.       else
  95.         {
  96.           fprintf (stderr, "Data larger that 16k!\n");
  97.           exit (-1);
  98.         }
  99.       rom_size = tag.len;
  100.       if (tag.len == 2048)
  101.         {
  102.           memcpy (&theCart[0], databuf, tag.len);
  103.           memcpy (&theCart[2048], databuf, tag.len);
  104.         }
  105.       break;
  106.  
  107.     default:
  108.       fprintf (stderr, "Unknown tag %d\n. Ignoring.", tag.type);
  109.       break;
  110.     }
  111.     }
  112.     return 1;
  113. }
  114.  
  115. /* Load a raw binary image  */
  116. /* fp: file stream to load */
  117. /* stat_data: unix stat structure for file pointed to by fp */
  118. /* returns: size of file loaded */
  119. int loadRaw (FILE * fp, long flen)
  120. {
  121.   int size = flen;
  122.   if (Verbose)
  123.     printf ("Raw loading %d bytes\n", size);
  124.  
  125.   if (size > 16384)
  126.     size = 16384;
  127.   fread (theCart, sizeof (UBYTE), size, fp);
  128.  
  129.   rom_size = size;
  130.   if (size == 2048)
  131.     {
  132.       memcpy (&theCart[2048], &theCart[0], 2048);
  133.       rom_size = 4096;
  134.     }
  135.   else if (size < 2048)
  136.     {
  137.       theCart[0x0ffc] = 0x00;
  138.       theCart[0x0ffd] = 0xf0;
  139.       rom_size = 4096;
  140.     }
  141.   
  142.   return size;
  143. }
  144.  
  145. /* Load a commodore format .prg file  */
  146. /* fp: file stream to load */
  147. /* stat_data: unix stat structure for file pointed to by fp */
  148. /* returns: size of file loaded */
  149. int loadPrg (FILE * fp, long flen)
  150. {
  151.   int start;
  152.   int rompos;
  153.   int size;
  154.   UBYTE buf1, buf2;
  155.  
  156.   /* Get the load address */
  157.   fread (&buf1, sizeof (UBYTE), 1, fp);
  158.   fread (&buf2, sizeof (UBYTE), 1, fp);
  159.   start = buf2 * 256 + buf1;
  160.  
  161.   /* Translate the load address to a ROM address */
  162.   rompos = start & 0xfff;
  163.  
  164.   /* Get length of data part */
  165.   size = flen - 2;
  166.  
  167.   if (Verbose)
  168.     printf ("Loading .prg at %x\n", start);
  169.  
  170.   /* Load the data */
  171.   fread (&theCart[rompos], sizeof (UBYTE), size, fp);
  172.  
  173.   /* Put the load address into the reset vector */
  174.   theCart[0x0ffc] = buf1;
  175.   theCart[0x0ffd] = buf2;
  176.   return size;
  177. }
  178.  
  179. /* Load a cartridge image */
  180. /* name: filename to load */
  181. /* returns: -1 on error 0 otherwise  */
  182. int loadCart (void)
  183. {
  184.   FILE *fp;
  185.   char *ext;
  186.   int flen;
  187.   char *name = base_opts.filename;
  188.  
  189.   if (name == NULL)
  190.     {
  191.       fprintf (stderr, "filename is NULL!\n");
  192.       return -1;
  193.     }
  194.  
  195.   fp = fopen (name, "rb");
  196.   if (!fp)
  197.     {
  198.       fprintf (stderr, "Can't find %s\n", name);
  199.       return -1;
  200.     }
  201.  
  202.   if (Verbose)
  203.     printf ("Loading cart: %s\n", name);
  204.   flen = filesize (fp);
  205.  
  206.   ext = strrchr (name, '.');
  207.   if (strcmp (".pal", ext) == 0 || strcmp (".vcs", ext) == 0 ||
  208.       strcmp (".raw", ext) == 0 || strcmp (".bin", ext) == 0 ||
  209.       strcmp (".BIN", ext) == 0)
  210.     {
  211.       loadRaw (fp, flen);
  212.     }
  213.   else if (strcmp (".prg", ext) == 0)
  214.     {
  215.       loadPrg (fp, flen);
  216.     }
  217.   else if (strcmp (".c26", ext) == 0)
  218.     {
  219.       loadc26 (fp, flen);
  220.     }
  221.   else
  222.     {
  223.       fprintf (stderr, "Unknown file format %s\n", ext);
  224.       return -1;
  225.     }
  226.   fclose (fp);
  227.   return 0;
  228. }
  229.